package com.atguigu.springcloud.core;

import cn.hutool.core.collection.CollectionUtil;
import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;
import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * @author xiaolong
 * @version 1.0
 * @description: TODO
 * @date 2021/10/14 13:58
 */
@Configuration
@Slf4j
public class HystrixConfiguration {

    @Autowired(required = false)
    private List<HystrixCallableWrapper> wrappers;


//    @Bean
//    public HystrixCallableWrapper requestAttributeAwareCallableWrapper(){
//        return new RequestCallableWrapper();
//    }

    @Bean
    public HystrixConcurrencyStrategy requestContextHystrixConcurrencyStrategy() {
        return new GosunHystrixConcurrencyStrategy(wrappers);
    }

    @PostConstruct
    public void init() {
        if (!CollectionUtil.isEmpty(wrappers)) {

            try {
                HystrixConcurrencyStrategy strategy = HystrixPlugins.getInstance().getConcurrencyStrategy();
                if (strategy instanceof GosunHystrixConcurrencyStrategy) {
                    return;
                }
                GosunHystrixConcurrencyStrategy hystrixConcurrencyStrategy = new GosunHystrixConcurrencyStrategy(wrappers);

                //获取原来的相关数据配置
                HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins
                        .getInstance().getCommandExecutionHook();
                HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance()
                        .getEventNotifier();
                HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance()
                        .getMetricsPublisher();
                HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance()
                        .getPropertiesStrategy();
                //打印日志
                if (log.isDebugEnabled()) {
                    log.debug("Current Hystrix plugins configuration is ["
                            + "concurrencyStrategy [" + hystrixConcurrencyStrategy + "]," + "eventNotifier ["
                            + eventNotifier + "]," + "metricPublisher [" + metricsPublisher + "],"
                            + "propertiesStrategy [" + propertiesStrategy + "]," + "]");
                    log.debug("Registering Sleuth Hystrix Concurrency Strategy.");
                }
                //重置再重新填充
                //直接设置会触发异常
                HystrixPlugins.reset();
                HystrixPlugins.getInstance().registerConcurrencyStrategy(hystrixConcurrencyStrategy);
                HystrixPlugins.getInstance()
                        .registerCommandExecutionHook(commandExecutionHook);
                HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
                HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
                HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
            } catch (Exception e) {
                log.error("Failed to register Sleuth Hystrix Concurrency Strategy", e);
            }
        }

    }
}

